package poo.alberi;

//************ Albero n-ario ************

import java.util.ArrayList;
import java.util.Iterator;

public class NTree<E> implements Tree<E> {

	private NNode<E> root;
	private int size;

	public NTree() {
		root = null;
		size = 0;
	}

	public NNode<E> addRoot(E e) {
		if (!isEmpty())
			throw new RuntimeException("L'albero ha gia una radice");

		NNode<E> r = new NNode<E>(e, null);
		root = r;
		size++;
		return r;
	}

	public int size() {
		return size;
	}

	public boolean isEmpty() {
		return root == null;
	}

	public Iterator<E> iterator() {
		return iterator(root, new ArrayList<E>()).iterator();
	}

	private ArrayList<E> iterator(Nodo<E> v, ArrayList<E> l) {
		for (Nodo<E> w : v.getChildren())
		l = iterator(w, l);
		l.add(v.getElement());
		return l;
	}

	public Iterable<Nodo<E>> nodes() {
		return nodes(root, new ArrayList<Nodo<E>>());
	}

	private ArrayList<Nodo<E>> nodes(Nodo<E> v, ArrayList<Nodo<E>> l) {
		for (Nodo<E> w : v.getChildren())
			l = nodes(w, l);
		l.add(v);
		return l;
	}

	public E replace(Nodo<E> v, E e) {
		E temp = v.getElement();
		v.setElement(e);
		return temp;
	}

	public Nodo<E> root() {
		if (isEmpty()) throw new RuntimeException("L'albero non ha radice");
		return root;
	}

	public Nodo<E> parent(Nodo<E> v) {
		return v.getParent();
	}

	public Nodo<E> addChildren(Nodo<E> v, E e) {
		Nodo<E> vv = new NNode<E>(e, v);
		v.getChildren().add(vv);
		size++;
		return vv;
	}

	public Iterable<Nodo<E>> children(Nodo<E> v) {
		return v.getChildren();
	}

	public boolean isInternal(Nodo<E> v) {
		return v.getChildren().size() != 0;

	}

	public boolean isExternal(Nodo<E> v) {
		return !isInternal(v);
	}

	public boolean isRoot(Nodo<E> v) {
		return v == root;
	}
}
